package com.sd365.permission.centre.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.sd365.common.core.annotation.stuffer.CommonFieldStuffer;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.annotation.stuffer.MethodTypeEnum;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.code.BusinessErrorCode;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.SystemParamMapper;
import com.sd365.permission.centre.entity.SystemParam;
import com.sd365.permission.centre.pojo.dto.CompanyDTO;
import com.sd365.permission.centre.pojo.dto.DeleteSystemParamDTO;
import com.sd365.permission.centre.pojo.dto.OrganizationDTO;
import com.sd365.permission.centre.pojo.dto.SystemParamDTO;
import com.sd365.permission.centre.pojo.query.SystemParameterFuzzyQuery;
import com.sd365.permission.centre.pojo.query.SystemParameterQuery;
import com.sd365.permission.centre.service.SystemParameterService;
import com.sd365.permission.centre.service.exception.UserCentreExceptionCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;

@Service
public class SystemParameterServiceImpl extends AbstractBaseDataServiceImpl implements SystemParameterService {

    @Autowired
    private SystemParamMapper systemParamMapper;
    @Autowired
    private IdGenerator idGenerator;

    @CommonFieldStuffer(methodType = MethodTypeEnum.ADD)
    @Override
    public Boolean add(@Valid SystemParamDTO systemParamDTO) {
        SystemParam systemParam = BeanUtil.copy(systemParamDTO, SystemParam.class);
        SystemParamDTO checkName = queryByName(systemParam.getParam());
        if (checkName != null) {
            return false;
        }
        systemParam.setId(idGenerator.snowflakeId());
        super.baseDataStuff4Add(systemParam);
        return systemParamMapper.insert(systemParam) > 0;
    }

    @Override
    public Boolean remove(Long id, Long version) {
        Example example = new Example(SystemParam.class);
        example.createCriteria().andEqualTo("id", id).andEqualTo("version", version);
        return systemParamMapper.deleteByExample(example) > 0;
    }

    @Override
    public Boolean modify(SystemParamDTO systemParamDTO) {
        SystemParam systemParam = BeanUtil.copy(systemParamDTO, SystemParam.class);
        super.baseDataStuff4Updated(systemParam);
        systemParam.setUpdatedTime(new Date());
        Example example = new Example(SystemParam.class);
        example.createCriteria().andEqualTo("id", systemParamDTO.getId()).andEqualTo("version", systemParamDTO.getVersion());
        return systemParamMapper.updateByExample(systemParam, example) > 0;
    }

    @Override
    public List<SystemParamDTO> commonQuery(SystemParameterQuery systemParameterQuery) {

        try {
            if (systemParameterQuery == null) {
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
            }
            SystemParam systemParam = new SystemParam();
            systemParam.setCompanyId(systemParameterQuery.getCompanyId());
            systemParam.setOrgId(systemParameterQuery.getOrgId());
            systemParam.setParamType(systemParameterQuery.getParamType());
            systemParam.setTenantId(systemParameterQuery.getTenantId());
            systemParam.setParam(systemParameterQuery.getParam());
            systemParam.setValue(systemParameterQuery.getValue());

            PageHelper.startPage(systemParameterQuery.getPageNum(), systemParameterQuery.getPageSize());

            List<SystemParam> systemParams = systemParamMapper.commonQuery(systemParam);
            Page page = (Page) systemParams;
            //将总数 页数拷贝到ThreadLocal
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));

            // 这里执行mybatis 高级查询
            List<SystemParamDTO> systemParamDTOS = BeanUtil.copyList(systemParams, SystemParamDTO.class, new BeanUtil.CopyCallback() {
                @Override
                public void copy(Object o, Object o1) {
                    // 调用 BeanUtil.copyProperties
                    if (o == null || o1 == null) {
                        throw new BeanException("拷贝对象不可以为空", new Exception("copyList 拷贝回调错误"));
                    }

                    SystemParam systemParamSource = (SystemParam) o;
                    SystemParamDTO systemParamDTO = (SystemParamDTO) o1;
                    systemParamDTO.setDictTypeName(systemParamSource.getDictionaryCategory().getName());
                }
            });
            return systemParamDTOS;
        } catch (BeanException ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        } catch (Exception ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_OTHER_EXCEPTION, ex);

        }
    }

    /**
     * 解决 commonQuery 参数类型仅能通过id查询的问题
     * @param systemParameterFuzzyQuery
     * @return List<SystemParamDTO>
     */
    @Override
    public List<SystemParamDTO> fuzzyQuery(SystemParameterFuzzyQuery systemParameterFuzzyQuery) {
        try {
            if (systemParameterFuzzyQuery == null) {
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
            }
            SystemParamDTO systemParamDTO = new SystemParamDTO();
            systemParamDTO.setCompanyId(systemParameterFuzzyQuery.getCompanyId());
            systemParamDTO.setOrgId(systemParameterFuzzyQuery.getOrgId());
            systemParamDTO.setTenantId(systemParameterFuzzyQuery.getTenantId());
            systemParamDTO.setDictTypeName(systemParameterFuzzyQuery.getParamType());
            systemParamDTO.setParam(systemParameterFuzzyQuery.getParam());
            systemParamDTO.setValue(systemParameterFuzzyQuery.getValue());
            List<SystemParam> systemParams = systemParamMapper.fuzzyQuery(systemParamDTO);
            Page page = (Page) systemParams;
            //将总数 页数拷贝到ThreadLocal
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));

            // 这里执行mybatis 高级查询
            List<SystemParamDTO> systemParamDTOS = BeanUtil.copyList(systemParams, SystemParamDTO.class, new BeanUtil.CopyCallback() {
                @Override
                public void copy(Object o, Object o1) {
                    // 调用 BeanUtil.copyProperties
                    if (o == null || o1 == null) {
                        throw new BeanException("拷贝对象不可以为空", new Exception("copyList 拷贝回调错误"));
                    }

                    SystemParam systemParamSource = (SystemParam) o;
                    SystemParamDTO systemParamDTO = (SystemParamDTO) o1;
                    systemParamDTO.setDictTypeName(systemParamSource.getDictionaryCategory().getName());
                }
            });
            return systemParamDTOS;
        } catch (BeanException ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        } catch (Exception ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_OTHER_EXCEPTION, ex);

        }
    }

    @Override
    public SystemParamDTO queryById(Long id) {
        SystemParamDTO systemParamDTO = null;
        SystemParam systemParam = systemParamMapper.selectById(id);
        if (systemParam != null) {
            systemParamDTO = BeanUtil.copy(systemParam, SystemParamDTO.class);
            BeanUtil.copy(systemParam.getDictionaryCategory(), systemParamDTO.getDictionaryTypeDTO(), SystemParamDTO.class);
            BeanUtil.copy(systemParam.getCompany(), systemParamDTO.getCompanyDTO(), CompanyDTO.class);
            BeanUtil.copy(systemParam.getOrganization(), systemParamDTO.getOrganizationDTO(), OrganizationDTO.class);
            systemParamDTO.setDictTypeName(systemParam.getDictionaryCategory().getName());
        }
        return systemParamDTO;
    }

    @Override
    public SystemParamDTO copy(Long id) {
        if (null == id) {
            throw new RuntimeException("传输参数为空异常:copy方法");
        }
        /**
         查询 id的客户信息
         修改 id 插入行的客户信息
         */
        try {
            SystemParam systemParam = systemParamMapper.selectById(id);
            if (systemParam != null) {
                systemParam.setId(idGenerator.snowflakeId());
                super.baseDataStuff4Updated(systemParam);
                if (systemParamMapper.insert(systemParam) > 0) {
                    SystemParamDTO systemParamDTO = BeanUtil.copy(systemParam, SystemParamDTO.class);
                    BeanUtil.copy(systemParam.getCompany(), systemParamDTO.getCompanyDTO(), CompanyDTO.class);
                    BeanUtil.copy(systemParam.getOrganization(), systemParamDTO.getOrganizationDTO(), OrganizationDTO.class);
                    return systemParamDTO;
                } else {
                    throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_CAR_TRAIL_DB_EXCEPTION_CODE, null);
                }
            } else {
                throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_CAR_TRAIL_DB_EXCEPTION_CODE, null);
            }
        } catch (BeanException ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        } catch (Exception ex) {
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_CAR_TRAIL_DB_EXCEPTION_CODE, ex);
        }
    }

    @Override
    public Boolean batchDelete(DeleteSystemParamDTO[] deleteSystemParamDTOS) {
        Assert.notEmpty(deleteSystemParamDTOS, "批量删除参数不可以为空");
        SystemParam[] systemParams = new SystemParam[deleteSystemParamDTOS.length];
        int i = 0;
        for (DeleteSystemParamDTO deleteSystemParamDTO : deleteSystemParamDTOS) {
            SystemParam systemParam = new SystemParam();
            systemParam.setId(deleteSystemParamDTO.getId());
            systemParam.setVersion(deleteSystemParamDTO.getVersion());
            systemParams[i] = systemParam;
            i++;
            Example example = new Example(SystemParam.class);
            example.createCriteria().andEqualTo("id", deleteSystemParamDTO.getId()).andEqualTo("version", deleteSystemParamDTO.getVersion());
            int result = systemParamMapper.deleteByExample(example);
            Assert.isTrue(result > 0, String.format("删除的记录id %d 没有匹配到版本", deleteSystemParamDTO.getId()));
        }

//        sendMessage.SendMessage(ActionType.DELETE,EXCHANGE_NAME,TABLE_NAME,customerWarehouses);
        return true;
    }

    @Override
    public Boolean batchUpdate(SystemParamDTO[] systemParamDTOS) {
        Assert.noNullElements(systemParamDTOS, "更新数组不能为空");
        for (SystemParamDTO systemParamDTO : systemParamDTOS) {
            SystemParam systemParam = BeanUtil.copy(systemParamDTO, SystemParam.class);
            Example example = new Example(systemParam.getClass());
            example.createCriteria().andEqualTo("id", systemParam.getId()).andEqualTo("version", systemParamDTO.getVersion());
            super.baseDataStuff4Updated(systemParam);
            int result = systemParamMapper.updateByExampleSelective(systemParam, example);
            Assert.isTrue(result > 0, "没有找到相应id更新记录");
        }
        return true;
    }

    @Override
    public SystemParamDTO queryByName(String name) {
        SystemParamDTO systemParamDTO = null;
        SystemParam systemParam = systemParamMapper.queryByName(name);
        if (systemParam != null) {
            systemParamDTO = BeanUtil.copy(systemParam, SystemParamDTO.class);
            BeanUtil.copy(systemParam.getDictionaryCategory(), systemParamDTO.getDictionaryTypeDTO(), SystemParamDTO.class);
            BeanUtil.copy(systemParam.getCompany(), systemParamDTO.getCompanyDTO(), CompanyDTO.class);
            BeanUtil.copy(systemParam.getOrganization(), systemParamDTO.getOrganizationDTO(), OrganizationDTO.class);
        }
        return systemParamDTO;
    }
}
